/* eslint-disable @typescript-eslint/no-unsafe-function-type */
/* eslint-disable @typescript-eslint/no-explicit-any */

// tsx-only
// import "reflect-metadata";

type DefineValidationType = { index: number; rule: string };

// 方法装饰器执行验证
function Validate(): MethodDecorator {
  return function (
    target: NewableFunction,
    methodName: string,
    descriptor: PropertyDescriptor,
  ): void {
    const originalMethod = descriptor.value!;
    const validations: DefineValidationType[] =
      Reflect.getMetadata("validations", target, methodName) ?? [];

    descriptor.value = function (this: any, ...args: any[]) {
      for (const { index, rule } of validations) {
        console.log(`args[${index}]:`, args[index]);
        if (rule === "not-null" && args[index] === null) {
          throw new Error(`参数 ${index} 不能为空！`);
        }
      }
      return originalMethod.apply(this, args);
    };
  } as MethodDecorator;
}

// 参数装饰器记录非空验证,
function NotNull(): ParameterDecorator {
  // 如果 NotNull 在构造器上的参数使用则 methodName 会返回 undefined
  return ((target: Function, methodName: string, parameterIndex: number) => {
    // 存储参数索引和验证规则
    const validations: DefineValidationType[] =
      Reflect.getMetadata("validations", target, methodName) || [];
    validations.push({ index: parameterIndex, rule: "not-null" });
    Reflect.defineMetadata("validations", validations, target, methodName);
  }) as ParameterDecorator; /** assert methodName */
}

// 使用示例
class UserService {
  @Validate()
  createUser(@NotNull() name: string): void {
    console.log(`用户 ${name} 已创建`);
  }
}

const service: UserService = new UserService();
service.createUser("Alice"); // 正常
service.createUser(null!); // 抛出错误: 参数 0 不能为空！

export default service;
